package pl.wroc.uni.ii.evolution.engine.prototype;
import pl.wroc.uni.ii.evolution.engine.EvAlgorithm;

/**
 * Encapsulates all information about a given evolutionary task,
 * that means: algorithm, objective function, all necessary parameters.
 * 
 * @author Marcin Brodziak, Tomasz Kozakiewicz, Marcin Golebiowski
 */
public class EvTask implements Runnable {

  protected EvAlgorithm algorithm = null;
  
  
  /**
   * Sets evolutionary algorithm for this task
   * @param algorithm
   */
  public void setAlgorithm(EvAlgorithm algorithm) {
    
    if (algorithm == null) {
      throw new IllegalArgumentException("You have called a setAlgoritm function with the algorithm equals to null");
    }
    
    this.algorithm = algorithm;
  }
  

  
  

  /**
   * Methods that runs algorithm basing on termination condition.
   */
  @SuppressWarnings({ "unchecked", "deprecation" })
  public void run() {
   
    if(algorithm == null) {
      throw new IllegalStateException(
      "Run method of EvolutionaryTask required to call setAlgorithm(EvolutionaryAlgorithm) first.");
    }

    // init algorithm
    algorithm.init();
    while (!algorithm.isTerminationConditionSatisfied()) {

      // do one algorithm iteration
      algorithm.doIteration();
    }
  }

  /**
   * Prints best result. 
   */
  public void printBestResult() {
    if(algorithm == null) {
      throw new IllegalStateException(
          "Print best result method of EvolutionaryTask required to call setAlgorithm(EvolutionaryAlgorithm) first.");
    }
    if(algorithm.getBestResult() == null) {
      throw new IllegalStateException(
          "Print best result method of EvolutionaryTask required to call run() first.");
    }    
    
    System.out.println(algorithm.getBestResult());
  }
  
  /**
   * Return best result individual.
   */
  public EvIndividual getBestResult() {
    if(algorithm == null) {
      throw new IllegalStateException(
          "Get best result method of EvolutionaryTask required to call setAlgorithm(EvolutionaryAlgorithm) first.");
    }
    if(algorithm.getBestResult() == null) {
      throw new IllegalStateException(
          "Get best result method of EvolutionaryTask required to call run() first.");
    }    
    
    return algorithm.getBestResult();
  }

}
